package com.ruoyi.common.utils.bean

import org.springframework.beans.BeanUtils
import java.lang.reflect.Method
import java.util.regex.Pattern

/**
 * Bean 工具类
 *
 * @author ruoyi
 */
object BeanUtils : BeanUtils() {
    /** Bean方法名中属性名开始的下标  */
    private const val BEAN_METHOD_PROP_INDEX = 3

    /** * 匹配getter方法的正则表达式  */
    private val GET_PATTERN = Pattern.compile("get(\\p{javaUpperCase}\\w*)")

    /** * 匹配setter方法的正则表达式  */
    private val SET_PATTERN = Pattern.compile("set(\\p{javaUpperCase}\\w*)")

    /**
     * Bean属性复制工具方法。
     *
     * @param dest 目标对象
     * @param src 源对象
     */
    fun copyBeanProp(dest: Any?, src: Any?) {
        try {
            copyProperties(src, dest)
        } catch (e: Exception) {
            e.printStackTrace()
        }
    }

    /**
     * 获取对象的setter方法。
     *
     * @param obj 对象
     * @return 对象的setter方法列表
     */
    fun getSetterMethods(obj: Any): List<Method> {
        // setter方法列表
        val setterMethods: MutableList<Method> = mutableListOf()

        // 获取所有方法
        val methods = obj.javaClass.methods

        // 查找setter方法
        for (method in methods) {
            val m = SET_PATTERN.matcher(method.name)
            if (m.matches() && method.parameterTypes.size == 1) {
                setterMethods.add(method)
            }
        }
        // 返回setter方法列表
        return setterMethods
    }

    /**
     * 获取对象的getter方法。
     *
     * @param obj 对象
     * @return 对象的getter方法列表
     */
    fun getGetterMethods(obj: Any): List<Method> {
        // getter方法列表
        val getterMethods: MutableList<Method> = mutableListOf()
        // 获取所有方法
        val methods = obj.javaClass.methods
        // 查找getter方法
        for (method in methods) {
            val m = GET_PATTERN.matcher(method.name)
            if (m.matches() && method.parameterTypes.isEmpty()) {
                getterMethods.add(method)
            }
        }
        // 返回getter方法列表
        return getterMethods
    }

    /**
     * 检查Bean方法名中的属性名是否相等。<br></br>
     * 如getName()和setName()属性名一样，getName()和setAge()属性名不一样。
     *
     * @param m1 方法名1
     * @param m2 方法名2
     * @return 属性名一样返回true，否则返回false
     */
    fun isMethodPropEquals(m1: String, m2: String): Boolean {
        return m1.substring(BEAN_METHOD_PROP_INDEX) == m2.substring(BEAN_METHOD_PROP_INDEX)
    }
}
